#coding=gb18030
import smtplib
import logging
import types

from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
import taskresult.base
import task
import datetime
import string

import chardet
from taskflow import taskflowtemplate

def StringToUnicode(s):
    if isinstance(s, types.UnicodeType):
        return s
    elif isinstance(s, types.StringType):
        return s.decode(chardet.detect(s)['encoding'])
    else:
        return s

CASE_CSS_LABEL = {taskresult.base.PASS:"<td class = 'resultTDSuccess'>Success</td>",
             taskresult.base.FAILURE:"<td class = 'resultTDFail'>Fail</td>",
             taskresult.base.ERROR:"<td class = 'resultTDException'>Exception</td>",
             taskresult.base.NORUN:"<td class = 'resultTDCannotExcute'>NoExcute</td>"}

TASK_CSS_LABEL = {task.SUCCESS:"<td class = 'resultTDSuccess' align='center'>Success</td>",
             task.FAILURE:"<td class = 'resultTDFail' align='center'>Fail</td>",
             task.EXCEPTION:"<td class = 'resultTDException' align='center'>Exception</td>"}


TASK_FLOW_CSS_LABEL = {taskflowtemplate.FINISH:"<td class = 'resultTDSuccess' align='center'>Finish</td>",
                       taskflowtemplate.NOT_TRIGGER:"<td class = 'resultTDFail' align='center'>NoTrigger</td>"}


def DatetimeFormat(t):
    if isinstance(t, datetime.datetime):
        return t.strftime('%Y-%m-%d %H:%M:%S')
    else:
        return t
        

def GenerateMailcontent(taskname, subtasklist, caselist, filelist, additional_content):
    mailcontentlist = []
    try:
        # Add L46-53
        flag = True
        message = ''
        for v in additional_content: 
            if v.endswith('.True'):
                flag = False
                break
        if flag:  
            if len(caselist) != 0:
                f = open('mailtemplate.html', 'r')
            else:
                f = open('mailtemplate_nocase.html', 'r')
            message = StringToUnicode(f.read())
           
            casemessage = []
            for v in caselist:
                casemessage.append('<tr>')
                casemessage.append("<td class = 'resultTDNormal'>%s</td>" % v.name)
                casemessage.append(CASE_CSS_LABEL[v.result])
                casemessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(v.start_time))
                casemessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(v.end_time))
                if v.message and len(v.message) > 150:
                    v.message = v.message[:150] + " ..."
                casemessage.append("<td class = 'resultTDNormal'>%s</td>" % v.message)
                casemessage.append('</tr>')
            
            taskmessage = []
            for v in subtasklist:
                taskmessage.append('<tr>')
                taskmessage.append("<td class = 'resultTDNormal'>%s</td>" % v.id)
                taskmessage.append(TASK_CSS_LABEL[v.result])
                taskmessage.append("<td class = 'resultTDNormal'>%s</td>"  % v.ip)
                taskmessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(v.start_time))
                taskmessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(v.end_time))
                taskmessage.append("<td class = 'resultTDNormal'>%s</td>" % v.result_message)
                taskmessage.append('</tr>')
            if len(caselist) != 0:
                message = (message % (taskname, taskname, '\n'.join(casemessage), '\n'.join(taskmessage)))
            else:
                message = (message % (taskname, taskname, '\n'.join(taskmessage)))
            message = StringToUnicode(message)
           
        for v in additional_content:
            f = None
            try:
                f = open(v, 'rb')
                content = StringToUnicode(f.read())
                message  = message + content
            except Exception:
                logging.exception('get mail addtional content fail')
            finally:
                if f:
                    f.close()
        
        mailcontent = MIMEText(message.encode('utf-8'), 'html', 'utf-8')
        mailcontentlist.append(mailcontent)
        
        for v in filelist:
            f= None
            try:
                # Add 106-108
                if v.endswith('True'):
                    continue
                f = open(v, 'rb')
                attachcontent = MIMEBase('application', 'octet-stream')
                attachcontent.set_payload(f.read())
                encoders.encode_base64(attachcontent)
                print os.path.basename(v)
                attachcontent.add_header('Content-Disposition', 'attachment', filename= StringToUnicode(os.path.basename(v)).encode('utf-8'))
                mailcontentlist.append(attachcontent)
            except Exception:
                logging.exception('mail attch file file %s' % v)
            finally:
                if f:
                    f.close()
        return mailcontentlist
    except Exception as e:
        logging.exception('parse mail content error') 
        raise e
    
    
def GenerateMailcontentNorespond(taskname):
    '''
    Generate no respond task mail.
    '''
    message = ''
    mailcontentlist = []
    with open('mailtemplate_norespond.html', 'r') as f:
        message = StringToUnicode(f.read())
    
    try:
        message = message % (taskname, taskname, taskname)
        message = StringToUnicode(message)
        mailcontent = MIMEText(message.encode('utf-8'), 'html', 'utf-8')
        mailcontentlist.append(mailcontent)
    except Exception as msg:
        logging.exception(msg)
    return mailcontentlist
    
    
def GenerateTaskFlowMailcontent(task_flow):
    '''
    Generate task flow mail content.
    '''
    message = ''
    mailcontentlist = []
    taskname = task_flow.name
    with open('mailtemplate_taskflow.html', 'r') as f:
        message = StringToUnicode(f.read())
    try:
        taskflowmessage, taskflownodemessage = GenerateTaskFlowResult(task_flow)
        message_list = [taskname, taskname]
        message_list.extend(taskflowmessage)
        message_list.append('\n'.join(taskflownodemessage))
        message = (message % tuple(message_list))
        message = StringToUnicode(message)
        mailcontent = MIMEText(message.encode('utf-8'), 'html', 'utf-8')
        mailcontentlist.append(mailcontent)
    except Exception as msg:
        logging.exception(msg)
    return mailcontentlist


def GenerateTaskFlowResult(task_flow):
    '''
    Generate task flow result. Include node information.
    '''
    taskflowmessage = []
    taskflownodemessage = []
    try:
        task_number = task_flow.nodes_len
        success_number = 0
        fail_number = 0
        except_number = 0
        norun_number = 0
        for node in task_flow.task_nodes:
            if node.result == task.SUCCESS:
                success_number += 1
            elif node.result == task.FAILURE:
                fail_number += 1
            elif node.result == task.EXCEPTION:
                except_number += 1
        norun_number = task_number - success_number - fail_number - except_number
        taskflowmessage.append(TASK_CSS_LABEL[task_flow.result])
        taskflowmessage.extend([success_number, fail_number, except_number, norun_number, task_number])
        taskflowmessage.append(DatetimeFormat(task_flow.start_time))
        taskflowmessage.append(DatetimeFormat(task_flow.end_time))
        taskflowmessage.append(task_flow.message)
        for node in task_flow.task_nodes:
            taskflownodemessage.append('<tr>')
            taskflownodemessage.append("<td class = 'resultTDNormal'>%s</td>" % node.name)
            taskflownodemessage.append(TASK_FLOW_CSS_LABEL[node.status])
            taskflownodemessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(node.start_time))
            taskflownodemessage.append("<td class = 'resultTDNormal'>%s</td>" % DatetimeFormat(node.end_time))
            if node.result:
                taskflownodemessage.append(TASK_CSS_LABEL[node.result])
            else:
                taskflownodemessage.append("<td class = 'resultTDNormal'>%s</td>" % node.result)
            taskflownodemessage.append("<td class = 'resultTDNormal'>%s</td>" % node.result_message)
            taskflownodemessage.append('</tr>')
    except Exception as msg:
        logging.exception(msg)
    return taskflowmessage, taskflownodemessage 

        
def SendResultMail(smtconfig, receiver, subject, mailcontentlist):
    if isinstance(receiver, types.StringTypes):
        receiver = [ string.strip(v)  for v in receiver.split(';') if string.strip(v) != ""]
        receiver = set(receiver)
    
    print(receiver)
    server = None
    try:
        server = smtplib.SMTP(smtconfig.host, smtconfig.port)
        if len(smtconfig.password) != 0:
            server.login(smtconfig.user, smtconfig.password)
        msg = MIMEMultipart()
        msg['Subject'] = subject
        msg['From'] =  smtconfig.sender
        msg['To'] = ';'.join(receiver)
        
        for v in mailcontentlist:
            msg.attach(v)
        
        server.sendmail(smtconfig.sender, receiver, msg.as_string())
    except Exception as e:
        logging.exception('send mail fail')
        raise e
    finally:
        if server:
            server.close()
             
